package com.corpgovernment.common.passport.util;

import com.corpgovernment.common.enums.CardEnum;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

/***
 * @author zwmao
 * @version 1.0.0
 * @date 2023/10/16
 **/
public class NameUtil {
    private static final int NATION_LENGTH = 2;
    private static final String CHINA_NATIONALITY = "CN";
    private static final String TAIWAN_NATIONALITY = "TW";
    private static final String HONG_KONG_NATIONALITY = "HK";
    private static final String MACAO_NATIONALITY = "MO";

    public static boolean checkNationality(String nationality) {
        //国籍为空或字符串长度小于2，直接返回false
        if (nationality == null || nationality.length() < NATION_LENGTH) {
            return false;
        }
        //校验国籍前两个字符是否为"CN"
        String nation = String.valueOf(nationality.charAt(0)) + nationality.charAt(1);
        return nation.equals(CHINA_NATIONALITY) || nation.equals(TAIWAN_NATIONALITY) || nation.equals(HONG_KONG_NATIONALITY) || nation.equals(MACAO_NATIONALITY);
    }

    public static boolean checkCnName(String cnName) {
        //判断字符串内容是否都为中文的正则表达式
        String reg = "[\\u4e00-\\u9fa5]+";

        //中文姓名为空直接返回false
        if (cnName == null) {
            return false;
        }
        //校验是否都为中文
        return cnName.matches(reg);
    }

    public static boolean checkEnName(String enName) {
        //英文姓名为空或长度为0返回false
        if (enName.length() == 0) {
            return false;
        }

        //校验英文姓名的正则表达式
        String reg = "[a-zA-Z]+/[a-zA-Z]+";
        //英文姓名需全为英文字母且只包含一个'/'
        return enName.matches(reg);
    }

    public static boolean checkCardType(Integer cardType) {
        //证件类型为空，直接返回false
        if (cardType == null) {
            return false;
        }
        String type = String.valueOf(cardType);
        return CardEnum.PASSPROT.getType().equals(type) || CardEnum.FOREIGNER_LIVE_CARD.getType().equals(type);
    }

    public static boolean confirmNames(String fromName, String toName) {
        String[] fromSplit = fromName.split("/");
        String[] toSplit = toName.split("/");
        String target = fromSplit[0] + fromSplit[1];
        String dest1 = toSplit[0] + toSplit[1];
        String dest2 = toSplit[1] + toSplit[0];
        return StringUtils.equals(target, dest1, true) || StringUtils.equals(target, dest2, true);
    }

    public static Set<String> getAllPinyin(String chineseStr) throws BadHanyuPinyinOutputFormatCombination {
        //输出格式设置
        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
        /**
         * 输出大小写设置
         *
         * LOWERCASE:输出小写
         * UPPERCASE:输出大写
         */
        format.setCaseType(HanyuPinyinCaseType.UPPERCASE);

        /**
         * 输出音标设置
         *
         * WITH_TONE_MARK:直接用音标符（必须设置WITH_U_UNICODE，否则会抛出异常）
         * WITH_TONE_NUMBER：1-4数字表示音标
         * WITHOUT_TONE：没有音标
         */
        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);

        /**
         * 特殊音标ü设置
         *
         * WITH_V：用v表示ü
         * WITH_U_AND_COLON：用"u:"表示ü
         * WITH_U_UNICODE：直接用ü
         */
        format.setVCharType(HanyuPinyinVCharType.WITH_V);

        char[] hanYuArr = chineseStr.trim().toCharArray();
        Set<String> nameSet = new LinkedHashSet<>();
        for (int i = 0, len = hanYuArr.length; i < len; i++) {
            //匹配是否是汉字
            if (Character.toString(hanYuArr[i]).matches("[\\u4E00-\\u9FA5]+")) {
                //如果是多音字，返回多个拼音
                String[] pys = PinyinHelper.toHanyuPinyinStringArray(hanYuArr[i], format);
                if (nameSet.isEmpty()) {
                    nameSet.addAll(Arrays.asList(pys));
                } else {
                    Set<String> term = new HashSet<>();
                    for (String a1 : nameSet) {
                        for (String a2 : pys) {
                            term.add(a1 + a2);
                        }
                    }
                    nameSet = term;
                }
            } else {
                Set<String> term = new HashSet<>();
                for (String a : nameSet) {
                    term.add(a + hanYuArr[i]);
                }
                nameSet = term;
            }
        }

        return nameSet;
    }

    private NameUtil() {
    }
}
